package com.tangsm.spring.boot.validation.config.interceptor;

import com.tangsm.spring.boot.validation.util.HttpServletUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义拦截器
 *
 * @author tangsm
 * @since 2021/12/24
 */
@Component
public class WebInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(WebInterceptor.class);

    /**
     * 执行处理程序之前的拦截点
     *
     * @param request  当前的 HTTP 请求
     * @param response 当前的 HTTP 响应
     * @param handler  选择的处理程序执行，用于类型和/或实例评估
     * @return true-执行下一个，false-结束请求
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 记录请求开始时间
        request.setAttribute("requestTime", System.currentTimeMillis());

        // 请求方式
        String method = request.getMethod();
        // 请求地址
        StringBuffer url = request.getRequestURL();

        // 请求方法名称，URL错误方法名称为空
        String methodName = "";
        if(handler instanceof HandlerMethod) {
            methodName = ((HandlerMethod) handler).getMethod().getName();
        }
        log.info("请求方式：{}, 请求地址：{}, 拦截的方法：{}", method, url, methodName);

        // 请求URL中的查询字符串
        log.info("请求URL中的查询字符串:{}", request.getQueryString());

        // 请求参数
        log.info("请求参数：{}", HttpServletUtils.getRequestParam(request));

        // 获取请求体
        log.info("请求体：{}", HttpServletUtils.getBodyStr(request));

        return true;
    }

    /**
     * 成功执行处理程序后的拦截点
     *
     * @param request      当前的 HTTP 请求
     * @param response     当前的 HTTP 响应
     * @param handler      选择的处理程序执行，用于类型和/或实例评估
     * @param modelAndView 处理程序返回的ModelAndView （也可以为null ）
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) {
        StringBuffer url = request.getRequestURL();

        log.info("执行处理程序之前的拦截点, 请求地址：{}", url);
    }

    /**
     * 请求处理完成后的回调，即渲染视图后
     *
     * @param request  当前的 HTTP 请求
     * @param response 当前的 HTTP 响应
     * @param handler  开始异步执行的处理程序（或HandlerMethod ），用于类型和/或实例检查
     * @param ex       处理程序执行时抛出的任何异常，如果有的话； 这不包括已通过异常解析器处理的异常
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) {
        StringBuffer url = request.getRequestURL();
        long duration = (System.currentTimeMillis() - (Long) request.getAttribute("requestTime"));
        log.info("请求处理完成后的回调，请求地址：{}, 请求耗时：{}", url, duration);
    }
}
